bitkeeper revision 1.737 (403a06aeivKFHIf1N0Wp-yJEFUDIrw)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 23 Feb 2004 13:57:02 +0000 (13:57 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Mon, 23 Feb 2004 13:57:02 +0000 (13:57 +0000)
serial.h:
  new file
Many files:
  Rewritten serial and console I/O for Xen. New command-line options (see the docs). ser_baud is deprecated.
Xeno-HOWTO.txt:
  Rename: docs/Xeno-1.2-HOWTO.txt -> docs/Xeno-HOWTO.txt
serial.c:
  Rename: xen/drivers/char/xen_serial.c -> xen/drivers/char/serial.c

18 files changed:
.rootkeys
README.CD
docs/Xeno-1.2-HOWTO.txt [deleted file]
docs/Xeno-HOWTO.txt [new file with mode: 0644]
xen/arch/i386/boot/boot.S
xen/arch/i386/nmi.c
xen/arch/i386/pdb-stub.c
xen/arch/i386/setup.c
xen/common/domain.c
xen/common/kernel.c
xen/common/keyhandler.c
xen/common/memory.c
xen/drivers/char/serial.c [new file with mode: 0644]
xen/drivers/char/xen_serial.c [deleted file]
xen/include/xeno/config.h
xen/include/xeno/console.h
xen/include/xeno/lib.h
xen/include/xeno/serial.h [new file with mode: 0644]

index bd163ff5e115817ec03402342aab3fe5e11dda52..15ed120cc5162f7fe2cab6413ce3c62bc28e2dd1 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
@@ -8,7 +8,7 @@
 3f69d8abYB1vMyD_QVDvzxy5Zscf1A TODO
 3f9e7d53iC47UnlfORp9iC1vai6kWw docs/Makefile
 40083bb4LVQzRqA3ABz0__pPhGNwtA docs/VBD-HOWTO.txt
-4021053fmeFrEyPHcT8JFiDpLNgtHQ docs/Xeno-1.2-HOWTO.txt
+4021053fmeFrEyPHcT8JFiDpLNgtHQ docs/Xeno-HOWTO.txt
 3f9e7d60PWZJeVh5xdnk0nLUdxlqEA docs/eps/xenlogo.eps
 3f9e7d63lTwQbp2fnx7yY93epWS-eQ docs/figs/dummy
 3f9e7d564bWFB-Czjv1qdmE6o0GqNg docs/interface.tex
 3e9c248afxxsnAzIt2na7Ej24yNFzg xen/drivers/cdrom/Makefile
 3e9c248ajUkn2W3n4vgm72Hp2ftZ8A xen/drivers/cdrom/cdrom.c
 3e4a8cb7alzQCDKS7MlioPoHBKYkdQ xen/drivers/char/Makefile
+3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/serial.c
 3e4a8cb7WmiYdC-ASGiCSG_CL8vsqg xen/drivers/char/xen_kbd.c
-3e4a8cb7nMChlro4wvOBo76n__iCFA xen/drivers/char/xen_serial.c
 3ddb79bdhcqD9ebrslr0O0oHqTiiXg xen/drivers/ide/Makefile
 3e9c248aCM6Lex1Am8_NJIeesN4kKg xen/drivers/ide/ide-cd.c
 3e9c248aFfSNR_hl-WQBbv-R9CTgzg xen/drivers/ide/ide-cd.h
 4006e65fWMwLqcocgik6wbF0Eeh0Og xen/include/xeno/rbtree.h
 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/include/xeno/reboot.h
 3ddb79c0LzqqS0LhAQ50ekgj4oGl7Q xen/include/xeno/sched.h
+403a06a7H0hpHcKpAiDe5BPnaXWTlA xen/include/xeno/serial.h
 3ddb79c0VDeD-Oft5eNfMneTU3D1dQ xen/include/xeno/skbuff.h
 3ddb79c14dXIhP7C2ahnoD08K90G_w xen/include/xeno/slab.h
 3ddb79c09xbS-xxfKxuV3JETIhBzmg xen/include/xeno/smp.h
index 8bbd212c09c0a678e219a1046f239bedb4eddd43..e9d172f268e08147d5e98fde8b8ec6e7b1d38d6a 100644 (file)
--- a/README.CD
+++ b/README.CD
@@ -76,7 +76,7 @@ sequentially for subsequent domains unless told otherwise.
 After selecting the kernel to boot, stand back and watch Xen boot,
 closely followed by "domain 0" running the XenoLinux kernel. The boot
 messages can also sent to the serial line by specifying the baud rate
-on the Xen cmdline (e.g., 'ser_baud=9600'); this can be very useful
+on the Xen cmdline (e.g., 'com1=9600,8n1'); this can be very useful
 for debugging should anything important scroll off the screen. Xen's
 startup messages will look quite familiar as much of the hardware
 initialisation (SMP boot, apic setup) and device drivers are derived
@@ -329,7 +329,31 @@ that may be able to help diagnose problems:
 
  ifname=dummy    Don't use any network interface.
 
- ser_baud=xxx    Enable serial I/O and set the baud rate (COM1)
+ com1=<baud>,DPS[,<io_base>,<irq>]
+ com2=<baud>,DPS[,<io_base>,<irq>]
+                  Xen supports up to two 16550-compatible serial ports.
+                  For example: 'com1=9600,8n1,0x408,5' maps COM1 to a
+                  9600-baud port, 8 data bits, no parity, 1 stop bit,
+                  I/O port base 0x408, IRQ 5.
+                  If the I/O base and IRQ are standard (com1:0x3f8,4;
+                  com2:0x2f8,3) then they need not be specified.
+
+ console=<specifier list>
+                  Specify the destination for Xen console I/O.
+                  This is a comma-separated list of, for example:
+                   vga:  use VGA console and allow keyboard input
+                   com1: use serial port com1
+                   com2H: use serial port com2. Transmitted chars will
+                          have the MSB set. Received chars must have
+                          MSB set.
+                   com2L: use serial port com2. Transmitted chars will
+                          have the MSB cleared. Received chars must
+                          have MSB cleared.
+                  The latter two examples allow a single port to be
+                  shared by two subsystems (eg. console and
+                  debugger). Sharing is controlled by MSB of each
+                  transmitted/received character.
+ [NB. Default for this option is 'com1,tty']
 
  dom0_mem=xxx    Set the initial amount of memory for domain0.
 
@@ -405,7 +429,7 @@ config file.
 A typical Grub menu option might look like:
 
 title Xen / XenoLinux 2.4.22
-        kernel /boot/image.gz dom0_mem=131072 ser_baud=115200 noht
+        kernel /boot/image.gz dom0_mem=131072 com1=115200,8n1 noht
         module /boot/xenolinux.gz root=/dev/sda4 ro console=tty0
 
 The first line specifies which Xen image to use, and what command line
diff --git a/docs/Xeno-1.2-HOWTO.txt b/docs/Xeno-1.2-HOWTO.txt
deleted file mode 100644 (file)
index fb89fe6..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-###########################################
-Xeno HOWTO
-
-University of Cambridge Computer Laboratory
-
-http://www.cl.cam.ac.uk/netos/xen
-#############################
-
-
-Get Xeno Source Codes
-==========================
-
-The public master BK repository for the 1.2 release lives at:
-'bk://xen.bkbits.net/xeno-1.2.bk'
-
-To fetch a local copy, first download the BitKeeper tools at:
-http://www.bitmover.com/download with username 'bitkeeper' and
-password 'get bitkeeper'.
-
-Then install the tools and then run:
-# bk clone bk://xen.bkbits.net/xeno-1.2.bk
-
-Under your current directory, a new directory named 'xeno-1.2.bk' has
-been created, which contains all the source codes for Xen and
-XenoLinux. 
-
-To get newest changes to the repository, run
-# cd xeno-1.2.bk
-# bk pull
-
-
-Build Xen
-=============================
-
-Hint: To see how to build Xen and all the control tools, inspect the
-tools/misc/xen-clone script in the BK repository. This script can be
-used to clone the repository and perform a full build.
-
-To build Xen manually:
-
-# cd xeno-1.2.bk/xen
-# make clean
-# make
-
-This will (should) produce a file called 'xen' in the current
-directory.  This is the ELF 32-bit LSB executable file of Xen.  You
-can also find a gzip version, named 'xen.gz'.
-
-To install the built files on your Xenoserver under /usr, type 'make
-install' at the root of the BK repository. You will need to be root to
-do this!
-
-Hint: There is also a 'make dist' rule which copies built files to an
-install directory just outside the BK repo; if this suits your setup,
-go for it.
-
-
-Build XenoLinux
-==============================
-
-This is a little more involved since the repository only contains a
-"sparse" tree -- this is essentially an 'overlay' on a standard linux
-kernel source tree. It contains only those files currently 'in play'
-which are either modified versions of files in the vanilla linux tree,
-or brand new files specific to XenoLinux.
-
-So, first you need a vanilla linux-2.4.24 tree, which is located at:
-http://www.kernel.org/pub/linux/kernel/v2.4
-
-Then:
-  # mv linux-2.4.24.tar.gz /xeno-1.2.bk
-  # cd /xeno-1.2.bk
-  # tar -zxvf linux-2.4.24.tar.gz
-
-You'll find a new directory 'linux-2.4.24' which contains all
-the vanilla Linux 2.4.24 kernel source codes.
-
-Hint: You should choose the vanilla linux kernel tree that has the
-same version as the "sparse" tree.
-
-Next, you need to 'overlay' this sparse tree on the full vanilla Linux
-kernel tree:
-
-  # cd /xeno-1.2.bk/xenolinux-2.4.24-sparse
-  # ./mkbuildtree ../linux-2.4.24
-
-Finally, rename the buildtree since it is now a xenolinux buildtree. 
-
-  # cd /xeno-1.2.bk
-  # mv linux-2.4.24 xenolinux-2.4.24
-
-Now that the buildtree is there, you can build the xenolinux kernel.
-The default configuration should work fine for most people (use 'make
-oldconfig') but you can customise using one of the other config tools
-if you want.
-
-  # cd /xeno-1.2.bk/xenolinux-2.4.24
-  # ARCH=xeno make oldconfig   { or menuconfig, or xconfig, or config }  
-  # ARCH=xeno make dep bzImage
-
-Assuming the build works, you'll end up with
-/xeno-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz. This is the
-gzip version of XenoLinux kernel image.
-
-
-Build the Domain Control Tools
-==============================
-
-Under '/xeno-1.2.bk/tools', there are three sub-directories:
-'balloon', 'xc' and 'misc', each containing
-a group of tools. You can enter any of the four sub-directories
-and type 'make' to compile the corresponding group of tools.
-Or you can type 'make' under '/xeno-1.2.bk/tools' to compile
-all the tools.
-
-In order to compile the control-interface library in 'xc' you must
-have zlib and development headers installed. Also you will need at
-least Python v2.2. 
-
-'make install' in the tools directory will place executables and
-libraries in /usr/bin and /usr/lib. You will need to be root to do this!
-
-As noted earlier, 'make dist' installs files to a local 'install'
-directory just outside the BK repository. These files will then need
-to be installed manually onto the Xenoserver.
-
-The Example Scripts
-===================
-
-The scripts in tools/examples/ are generally useful for
-administering a Xen-based system.  You can install them by running
-'make install' in that directory.
-
-The python scripts (*.py) are the main tools for controlling
-Xen domains.
-
-'defaults' and 'democd' are example configuration files for starting
-new domains.
-
-'xendomains' is a Sys-V style init script for starting and stopping
-Xen domains when the system boots / shuts down.
-
-These will be discussed below in more detail.
-
-
-Installation
-==============================
-
-First:
-# cp /xen-1.2.bk/xen/xen.gz /boot/xen.gz
-# cp /xen-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz /boot/xenolinux.gz
-
-Second, you must have 'GNU Grub' installed. Then you need to edit
-the Grub configuration file '/boot/grub/menu.lst'.
-
-A typical Grub menu option might look like:
-
-title Xen 1.2 / XenoLinux 2.4.24
-        kernel /boot/xen.gz dom0_mem=131072 ser_baud=115200 noht
-        module /boot/xenolinux.gz root=/dev/sda4 ro console=tty0
-
-The first line specifies which Xen image to use, and what command line
-arguments to pass to Xen. In this case we set the maximum amount of
-memory to allocate to domain0, and enable serial I/O at 115200 baud.
-We could also disable smp support (nosmp) or disable hyper-threading
-support (noht). If you have multiple network interface you can use
-ifname=ethXX to select which one to use. If your network card is
-unsupported, use ifname=dummy
-
-The second line specifies which XenoLinux image to use, and the
-standard linux command line arguments to pass to the kernel. In this
-case, we're configuring the root partition and stating that it should
-(initially) be mounted read-only (normal practice). 
-
-The following is a list of command line arguments to pass to Xen:
-
- ignorebiostables Disable parsing of BIOS-supplied tables. This may
-                  help with some chipsets that aren't fully supported
-                  by Xen. If you specify this option then ACPI tables are
-                  also ignored, and SMP support is disabled.
-
- noreboot         Don't reboot the machine automatically on errors.
-                  This is useful to catch debug output if you aren't
-                  catching console messages via the serial line.
-
- nosmp            Disable SMP support.
-                  This option is implied by 'ignorebiostables'.
-
- noacpi           Disable ACPI tables, which confuse Xen on some chipsets.
-                  This option is implied by 'ignorebiostables'.
-
- watchdog         Enable NMI watchdog which can report certain failures.
-
- noht             Disable Hyperthreading.
-
- ifname=ethXX     Select which Ethernet interface to use.
-
- ifname=dummy     Don't use any network interface.
-
- ser_baud=xxx     Enable serial I/O and set the baud rate.
-
- dom0_mem=xxx     Set the maximum amount of memory for domain0.
-
-
-Boot into Domain 0
-==============================
-
-Reboot your computer; After selecting the kernel to boot, stand back
-and watch Xen boot, closely followed by "domain 0" running the
-XenoLinux kernel.  Depending on which root partition you have assigned
-to XenoLinux kernel in Grub configuration file, you can use the
-corresponding username / password to log in.
-
-Once logged in, it should look just like any regular linux box. All
-the usual tools and commands should work as per usual.
-
-
-Start New Domains
-==============================
-
-You must be 'root' to start new domains.
-
-Make sure you have successfully configured at least one
-physical network interface. Then:
-
-# xen_nat_enable
-# xen_read_console &
-
-When new  domains are created and  started, they will  send output via
-UDP packets to  the local virtual network. Those  packets are received
-by xen_read_console running in Domain  0 and output are printed out to
-the standard output.
-
-The xc_dom_create.py program is useful for starting Xen domains.
-You can specify configuration files using the -f switch on the command
-line.  The default configuration is in /etc/xc/defaults.  You can
-create custom versions of this to suit your local configuration.
-
-You can override the settings in a configuration file using command
-line arguments to xc_dom_create.py.  However, you may find it simplest
-to create a separate configuration file for each domain you start.
-
-When you start domains, you should be able to see XenoLinux boot
-message on standard output with each line prepended with [domain_id].
-
-
-Manage Running Domains
-==============================
-
-You can see a list of existing domains with:
-# xc_dom_control.py list
-
-In order to stop a domain, you use:
-# xc_dom_control.py stop <domain_id>
-
-To shutdown a domain cleanly use:
-# xc_dom_control.py shutdown <domain_id>
-
-To destroy a domain immediately:
-# xc_dom_control.py destroy <domain_id>
-
-There are other more advanced options, including pinning domains to
-specific CPUs and saving / resuming domains to / from disk files.  To
-get more information, run the tool without any arguments:
-# xc_dom_control.py
-
-There is more information available in the Xen README files, the
-VBD-HOWTO and the contributed FAQ / HOWTO documents on the web.
-
-
-Other Control Tasks using Python
-================================
-
-A Python module 'Xc' is installed as part of the tools-install
-process. This can be imported, and an 'xc object' instantiated, to
-provide access to privileged command operations:
-
-# import Xc
-# xc = Xc.new()
-# dir(xc)
-# help(xc.domain_create)
-
-In this way you can see that the class 'xc' contains useful
-documentation for you to consult.
-
-A further module of useful routines (XenoUtil) is also installed:
-
-# import XenoUtil
-# help(XenoUtil)
-
-You can use these modules to write your own custom scripts or you can
-customise the scripts supplied in the Xen distribution.
-
-
-Automatically start / stop domains at boot / shutdown
-=====================================================
-
-A Sys-V style init script for RedHat systems is provided in
-tools/examples/xendomains.  When you run 'make install' in that
-directory, it should be automatically copied to /etc/init.d/.  You can
-then enable it using the chkconfig command, e.g.:
-
-# chkconfig --add xendomains
-
-By default, this will start the boot-time domains in runlevels 3, 4
-and 5.  To specify a domain is to start at boot-time, place its
-configuration file (or a link to it) under /etc/xc/auto/.
-
-The script will also stop ALL domains when the system is shut down,
-even domains that it did not start originally.
-
-You can also use the "service" command (part of the RedHat standard
-distribution) to run this script manually, e.g:
-
-# service xendomains start
-
-Starts all the domains with config files under /etc/xc/auto/.
-
-# service xendomains stop
-
-Shuts down ALL running Xen domains.
diff --git a/docs/Xeno-HOWTO.txt b/docs/Xeno-HOWTO.txt
new file mode 100644 (file)
index 0000000..e30c747
--- /dev/null
@@ -0,0 +1,345 @@
+###########################################
+Xeno HOWTO
+
+University of Cambridge Computer Laboratory
+
+http://www.cl.cam.ac.uk/netos/xen
+#############################
+
+
+Get Xeno Source Codes
+==========================
+
+The public master BK repository for the 1.2 release lives at:
+'bk://xen.bkbits.net/xeno-1.2.bk'
+
+To fetch a local copy, first download the BitKeeper tools at:
+http://www.bitmover.com/download with username 'bitkeeper' and
+password 'get bitkeeper'.
+
+Then install the tools and then run:
+# bk clone bk://xen.bkbits.net/xeno-1.2.bk
+
+Under your current directory, a new directory named 'xeno-1.2.bk' has
+been created, which contains all the source codes for Xen and
+XenoLinux. 
+
+To get newest changes to the repository, run
+# cd xeno-1.2.bk
+# bk pull
+
+
+Build Xen
+=============================
+
+Hint: To see how to build Xen and all the control tools, inspect the
+tools/misc/xen-clone script in the BK repository. This script can be
+used to clone the repository and perform a full build.
+
+To build Xen manually:
+
+# cd xeno-1.2.bk/xen
+# make clean
+# make
+
+This will (should) produce a file called 'xen' in the current
+directory.  This is the ELF 32-bit LSB executable file of Xen.  You
+can also find a gzip version, named 'xen.gz'.
+
+To install the built files on your Xenoserver under /usr, type 'make
+install' at the root of the BK repository. You will need to be root to
+do this!
+
+Hint: There is also a 'make dist' rule which copies built files to an
+install directory just outside the BK repo; if this suits your setup,
+go for it.
+
+
+Build XenoLinux
+==============================
+
+This is a little more involved since the repository only contains a
+"sparse" tree -- this is essentially an 'overlay' on a standard linux
+kernel source tree. It contains only those files currently 'in play'
+which are either modified versions of files in the vanilla linux tree,
+or brand new files specific to XenoLinux.
+
+So, first you need a vanilla linux-2.4.24 tree, which is located at:
+http://www.kernel.org/pub/linux/kernel/v2.4
+
+Then:
+  # mv linux-2.4.24.tar.gz /xeno-1.2.bk
+  # cd /xeno-1.2.bk
+  # tar -zxvf linux-2.4.24.tar.gz
+
+You'll find a new directory 'linux-2.4.24' which contains all
+the vanilla Linux 2.4.24 kernel source codes.
+
+Hint: You should choose the vanilla linux kernel tree that has the
+same version as the "sparse" tree.
+
+Next, you need to 'overlay' this sparse tree on the full vanilla Linux
+kernel tree:
+
+  # cd /xeno-1.2.bk/xenolinux-2.4.24-sparse
+  # ./mkbuildtree ../linux-2.4.24
+
+Finally, rename the buildtree since it is now a xenolinux buildtree. 
+
+  # cd /xeno-1.2.bk
+  # mv linux-2.4.24 xenolinux-2.4.24
+
+Now that the buildtree is there, you can build the xenolinux kernel.
+The default configuration should work fine for most people (use 'make
+oldconfig') but you can customise using one of the other config tools
+if you want.
+
+  # cd /xeno-1.2.bk/xenolinux-2.4.24
+  # ARCH=xeno make oldconfig   { or menuconfig, or xconfig, or config }  
+  # ARCH=xeno make dep bzImage
+
+Assuming the build works, you'll end up with
+/xeno-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz. This is the
+gzip version of XenoLinux kernel image.
+
+
+Build the Domain Control Tools
+==============================
+
+Under '/xeno-1.2.bk/tools', there are three sub-directories:
+'balloon', 'xc' and 'misc', each containing
+a group of tools. You can enter any of the four sub-directories
+and type 'make' to compile the corresponding group of tools.
+Or you can type 'make' under '/xeno-1.2.bk/tools' to compile
+all the tools.
+
+In order to compile the control-interface library in 'xc' you must
+have zlib and development headers installed. Also you will need at
+least Python v2.2. 
+
+'make install' in the tools directory will place executables and
+libraries in /usr/bin and /usr/lib. You will need to be root to do this!
+
+As noted earlier, 'make dist' installs files to a local 'install'
+directory just outside the BK repository. These files will then need
+to be installed manually onto the Xenoserver.
+
+The Example Scripts
+===================
+
+The scripts in tools/examples/ are generally useful for
+administering a Xen-based system.  You can install them by running
+'make install' in that directory.
+
+The python scripts (*.py) are the main tools for controlling
+Xen domains.
+
+'defaults' and 'democd' are example configuration files for starting
+new domains.
+
+'xendomains' is a Sys-V style init script for starting and stopping
+Xen domains when the system boots / shuts down.
+
+These will be discussed below in more detail.
+
+
+Installation
+==============================
+
+First:
+# cp /xen-1.2.bk/xen/xen.gz /boot/xen.gz
+# cp /xen-1.2.bk/xenolinux-2.4.24/arch/xeno/boot/xenolinux.gz /boot/xenolinux.gz
+
+Second, you must have 'GNU Grub' installed. Then you need to edit
+the Grub configuration file '/boot/grub/menu.lst'.
+
+A typical Grub menu option might look like:
+
+title Xen 1.2 / XenoLinux 2.4.24
+        kernel /boot/xen.gz dom0_mem=131072 com1=115200,8n1 noht
+        module /boot/xenolinux.gz root=/dev/sda4 ro console=tty0
+
+The first line specifies which Xen image to use, and what command line
+arguments to pass to Xen. In this case we set the maximum amount of
+memory to allocate to domain0, and enable serial I/O at 115200 baud.
+We could also disable smp support (nosmp) or disable hyper-threading
+support (noht). If you have multiple network interface you can use
+ifname=ethXX to select which one to use. If your network card is
+unsupported, use ifname=dummy
+
+The second line specifies which XenoLinux image to use, and the
+standard linux command line arguments to pass to the kernel. In this
+case, we're configuring the root partition and stating that it should
+(initially) be mounted read-only (normal practice). 
+
+The following is a list of command line arguments to pass to Xen:
+
+ ignorebiostables Disable parsing of BIOS-supplied tables. This may
+                  help with some chipsets that aren't fully supported
+                  by Xen. If you specify this option then ACPI tables are
+                  also ignored, and SMP support is disabled.
+
+ noreboot         Don't reboot the machine automatically on errors.
+                  This is useful to catch debug output if you aren't
+                  catching console messages via the serial line.
+
+ nosmp            Disable SMP support.
+                  This option is implied by 'ignorebiostables'.
+
+ noacpi           Disable ACPI tables, which confuse Xen on some chipsets.
+                  This option is implied by 'ignorebiostables'.
+
+ watchdog         Enable NMI watchdog which can report certain failures.
+
+ noht             Disable Hyperthreading.
+
+ ifname=ethXX     Select which Ethernet interface to use.
+
+ ifname=dummy     Don't use any network interface.
+
+ com1=<baud>,DPS[,<io_base>,<irq>]
+ com2=<baud>,DPS[,<io_base>,<irq>]
+                  Xen supports up to two 16550-compatible serial ports.
+                  For example: 'com1=9600,8n1,0x408,5' maps COM1 to a
+                  9600-baud port, 8 data bits, no parity, 1 stop bit,
+                  I/O port base 0x408, IRQ 5.
+                  If the I/O base and IRQ are standard (com1:0x3f8,4;
+                  com2:0x2f8,3) then they need not be specified.
+
+ console=<specifier list>
+                  Specify the destination for Xen console I/O.
+                  This is a comma-separated list of, for example:
+                   vga:  use VGA console and allow keyboard input
+                   com1: use serial port com1
+                   com2H: use serial port com2. Transmitted chars will
+                          have the MSB set. Received chars must have
+                          MSB set.
+                   com2L: use serial port com2. Transmitted chars will
+                          have the MSB cleared. Received chars must
+                          have MSB cleared.
+                  The latter two examples allow a single port to be
+                  shared by two subsystems (eg. console and
+                  debugger). Sharing is controlled by MSB of each
+                  transmitted/received character.
+ [NB. Default for this option is 'com1,tty']
+
+ dom0_mem=xxx     Set the maximum amount of memory for domain0.
+
+
+Boot into Domain 0
+==============================
+
+Reboot your computer; After selecting the kernel to boot, stand back
+and watch Xen boot, closely followed by "domain 0" running the
+XenoLinux kernel.  Depending on which root partition you have assigned
+to XenoLinux kernel in Grub configuration file, you can use the
+corresponding username / password to log in.
+
+Once logged in, it should look just like any regular linux box. All
+the usual tools and commands should work as per usual.
+
+
+Start New Domains
+==============================
+
+You must be 'root' to start new domains.
+
+Make sure you have successfully configured at least one
+physical network interface. Then:
+
+# xen_nat_enable
+# xen_read_console &
+
+When new  domains are created and  started, they will  send output via
+UDP packets to  the local virtual network. Those  packets are received
+by xen_read_console running in Domain  0 and output are printed out to
+the standard output.
+
+The xc_dom_create.py program is useful for starting Xen domains.
+You can specify configuration files using the -f switch on the command
+line.  The default configuration is in /etc/xc/defaults.  You can
+create custom versions of this to suit your local configuration.
+
+You can override the settings in a configuration file using command
+line arguments to xc_dom_create.py.  However, you may find it simplest
+to create a separate configuration file for each domain you start.
+
+When you start domains, you should be able to see XenoLinux boot
+message on standard output with each line prepended with [domain_id].
+
+
+Manage Running Domains
+==============================
+
+You can see a list of existing domains with:
+# xc_dom_control.py list
+
+In order to stop a domain, you use:
+# xc_dom_control.py stop <domain_id>
+
+To shutdown a domain cleanly use:
+# xc_dom_control.py shutdown <domain_id>
+
+To destroy a domain immediately:
+# xc_dom_control.py destroy <domain_id>
+
+There are other more advanced options, including pinning domains to
+specific CPUs and saving / resuming domains to / from disk files.  To
+get more information, run the tool without any arguments:
+# xc_dom_control.py
+
+There is more information available in the Xen README files, the
+VBD-HOWTO and the contributed FAQ / HOWTO documents on the web.
+
+
+Other Control Tasks using Python
+================================
+
+A Python module 'Xc' is installed as part of the tools-install
+process. This can be imported, and an 'xc object' instantiated, to
+provide access to privileged command operations:
+
+# import Xc
+# xc = Xc.new()
+# dir(xc)
+# help(xc.domain_create)
+
+In this way you can see that the class 'xc' contains useful
+documentation for you to consult.
+
+A further module of useful routines (XenoUtil) is also installed:
+
+# import XenoUtil
+# help(XenoUtil)
+
+You can use these modules to write your own custom scripts or you can
+customise the scripts supplied in the Xen distribution.
+
+
+Automatically start / stop domains at boot / shutdown
+=====================================================
+
+A Sys-V style init script for RedHat systems is provided in
+tools/examples/xendomains.  When you run 'make install' in that
+directory, it should be automatically copied to /etc/init.d/.  You can
+then enable it using the chkconfig command, e.g.:
+
+# chkconfig --add xendomains
+
+By default, this will start the boot-time domains in runlevels 3, 4
+and 5.  To specify a domain is to start at boot-time, place its
+configuration file (or a link to it) under /etc/xc/auto/.
+
+The script will also stop ALL domains when the system is shut down,
+even domains that it did not start originally.
+
+You can also use the "service" command (part of the RedHat standard
+distribution) to run this script manually, e.g:
+
+# service xendomains start
+
+Starts all the domains with config files under /etc/xc/auto/.
+
+# service xendomains stop
+
+Shuts down ALL running Xen domains.
index f0e5a57c75f2c2f7f721a4c28f2459b914e0470c..4d9204ce45047952389eb21c98b893444207a51c 100644 (file)
@@ -186,30 +186,14 @@ ignore_int:
         pushl   $int_msg
         call    SYMBOL_NAME(printf)
 1:      jmp     1b
-        pop     %eax
-        popl    %ds
-        popl    %es
-        pop     %edx
-        pop     %ecx
-        pop     %eax
-        iret
-
 
 bad_cpu_msg:
         .asciz  "Bad CPU type. Need P6+."
         ALIGN
 bad_cpu:
-/* NB. We assume the UART is set up correctly. */
-        mov     $bad_cpu_msg,%esi
-1:      lodsb
-        test    %al,%al
-        je      1f
-        push    %eax
-        call    putchar_serial
-        add     $4,%esp
-        jmp     1b
+        pushl   $bad_cpu_msg
+        call    SYMBOL_NAME(printf)
 1:      jmp     1b
-                   
         
 /*** STACK LOCATION ***/
         
index a2555752aea6d76a356183105e441623fdbdf951..16aace462db5a35bde647f5355d3c0d4064a5289 100644 (file)
@@ -276,7 +276,6 @@ void nmi_watchdog_tick (struct pt_regs * regs)
 {
     extern spinlock_t console_lock;
     extern void die(const char * str, struct pt_regs * regs, long err);
-    extern void putchar_serial(unsigned char c);
 
     int sum, cpu = smp_processor_id();
 
index f56abae0049e29c68cfdd696c850a806004961a9..87fb907fb8fe94f3d79680691ab7b6154b72aa82 100644 (file)
@@ -5,6 +5,7 @@
 #include <asm/apic.h>
 #include <asm/pdb.h>
 #include <xeno/list.h>
+#include <xeno/serial.h>
 
 #define BUFMAX 400
 
@@ -27,8 +28,32 @@ static int pdb_info_thread = -1;
 static int pdb_stepping = 0;
 
 void pdb_put_packet (unsigned char *buffer, int ack);
-void pdb_put_char (u_char c);
-u_char pdb_get_char ();
+
+static int pdb_initialized = 0;
+static int pdb_serhnd      = -1;
+
+#define RX_SIZE 32
+#define RX_MASK(_i) ((_i)&(RX_SIZE-1))
+static unsigned int rx_cons = 0, rx_prod = 0;
+static unsigned char rx_ring[RX_RING_SIZE];
+
+static inline void pdb_put_char(unsigned char c)
+{
+    serial_putc(pdb_serhnd, c);
+}
+
+static inline unsigned char pdb_get_char(void)
+{
+    while ( rx_cons == rx_prod )
+        barrier();
+    return rx_ring[RX_MASK(rx_cons++)];
+}
+
+static void pdb_rx_char(unsigned char c, struct pt_regs *regs)
+{
+    if ( (rx_prod - rx_cons) != RX_SIZE )
+        rx_ring[RX_MASK(rx_prod++)] = c;
+}
 
 static volatile int mem_err = 0;
 void set_mem_err (void)                                   /* NOT USED YET... */
@@ -635,23 +660,6 @@ int pdb_bkpt_remove (unsigned long address)
 
 void breakpoint(void);
 
-int pdb_initialized = 0;
-int pdb_high_bit = 1;
-
-void pdb_put_char (u_char c)
-{
-    extern void   debug_putchar(u_char);
-    u_char cc = pdb_high_bit ? c | 0x80 : c;
-    debug_putchar(cc);
-}
-
-u_char pdb_get_char ()
-{
-    extern u_char debug_getchar();
-    u_char cc = debug_getchar();
-    return cc & 0x7f;
-}
-
 /* send the packet in buffer.  */
 void pdb_put_packet (unsigned char *buffer, int ack)
 {
@@ -821,35 +829,28 @@ void pdb_key_pressed(u_char key, void *dev_id, struct pt_regs *regs)
 void initialize_pdb()
 {
     extern char opt_pdb[];
-    int pdb_com_port;
 
     /* Certain state must be initialised even when PDB will not be used. */
     breakpoints.address = 0;
     INIT_LIST_HEAD(&breakpoints.list);
     pdb_stepping = 0;
 
-    if ( strncmp(opt_pdb, "com", 3) == 0 )
-    {
-        extern void debug_set_com_port(int port);
+    if ( strcmp(opt_pdb, "none") == 0 )
+        return;
 
-        pdb_com_port = opt_pdb[3] - '0';                 /* error checking ? */
-       debug_set_com_port(pdb_com_port);
-       pdb_high_bit = opt_pdb[4] == 'H' ? 1 : 0;
-    }
-    else
+    if ( (pdb_serhnd = parse_serial_handle(opt_pdb)) == -1 )
     {
-        if ( strcmp(opt_pdb, "none") != 0 )
-           printk ("pdb: unknown option\n");
+        printk("Failed to initialise PDB on port %s\n", opt_pdb);
         return;
     }
 
-    printk("Initializing pervasive debugger (PDB) on serial port %d %s\n",
-           pdb_com_port, pdb_high_bit ? "(high bit enabled)" : "");
+    serial_set_rx_handler(pdb_serhnd, pdb_rx_char);
+
+    printk("Initialised pervasive debugger (PDB) on port %s\n", opt_pdb);
 
-    /* ack any spurrious gdb packets */
-    pdb_put_char ('+');
+    /* Acknowledge any spurious GDB packets. */
+    serial_putc(pdb_serhnd, '+');
 
-    /* serial console */
     add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
 
     pdb_initialized = 1;
index ee52629dee5525e4778a9099a2ef210095bdfe56..ac2df96139f868d1cf98964780a0b2fda0cee279 100644 (file)
@@ -5,6 +5,7 @@
 #include <xeno/lib.h>
 #include <xeno/sched.h>
 #include <xeno/pci.h>
+#include <xeno/serial.h>
 #include <asm/bitops.h>
 #include <asm/smp.h>
 #include <asm/processor.h>
@@ -316,7 +317,6 @@ void __init start_of_day(void)
     extern void net_init(void);
     extern void initialize_block_io(void);
     extern void initialize_keytable(); 
-    extern void initialize_serial(void);
     extern void initialize_keyboard(void);
     extern int opt_nosmp, opt_watchdog, opt_noacpi, opt_ignorebiostables;
     extern int do_timer_lists_from_pit;
@@ -406,6 +406,10 @@ void __init start_of_day(void)
 
     initialize_keytable(); /* call back handling for key codes      */
 
+    serial_init_stage2();
+    initialize_keyboard(); /* setup keyboard (also for debugging)   */
+    initialize_pdb();      /* pervasive debugger */
+
     if ( !cpu_has_apic )
     {
         do_timer_lists_from_pit = 1;
@@ -427,10 +431,6 @@ void __init start_of_day(void)
     pci_init();
 #endif
     do_initcalls();
-    initialize_serial();   /* setup serial 'driver' (for debugging) */
-    initialize_keyboard(); /* setup keyboard (also for debugging)   */
-    initialize_pdb();      /* pervasive debugger */
-
     if ( !setup_network_devices() )
         panic("Must have a network device!\n");
     net_init();            /* initializes virtual network system. */
index 4f45a88b914c00ad4a25f629707e8b6cea79ec7d..42461c25bef009e4b1a9d1bb72d60e64152c8993 100644 (file)
@@ -787,9 +787,9 @@ int setup_guestos(struct task_struct *p, dom0_createdomain_t *params,
     }
     *dst = '\0';
 
-    /* If this guy's getting the console we'd better let go. */
-    if ( CONSOLE_ISOWNER(p) )
-        opt_console = 0;
+    /* HACK: Give up the VGA console iff the Xenolinux DOM0 wants it. */
+    if ( strstr(cmdline, "tty0") != NULL )
+        vgacon_enabled = 0;
 
     /* Reinstate the caller's page tables. */
     write_cr3_counted(pagetable_val(current->mm.pagetable));
index 3554ec5b17d1f5be2f599681ebb0575140f8ec65..42d6b1f46f4a41ef02fbf92c44cfbca7e8a639fa 100644 (file)
 #include <asm/domain_page.h>
 #include <xeno/console.h>
 #include <xeno/net_headers.h>
+#include <xeno/serial.h>
 
 kmem_cache_t *task_struct_cachep;
 
 static int xpos, ypos;
-static volatile unsigned char *video;
+static unsigned char *video = __va(0xB8000);
+
+int sercon_handle = -1;
+int vgacon_enabled = 0;
 
 spinlock_t console_lock = SPIN_LOCK_UNLOCKED;
 
@@ -43,15 +47,17 @@ struct e820entry {
     unsigned long type;                    /* type of memory segment */
 };
 
-void init_vga(void);
-void init_serial(void);
+static void init_vga(void);
 void start_of_day(void);
 
-/* opt_console: If true, Xen sends logging to the VGA console. */
-int opt_console = 1;
+/* opt_console: comma-separated list of console outputs. */
+unsigned char opt_console[30] = "com1,vga";
 /* opt_ser_baud: Baud rate at which logging is sent to COM1. */
 /* NB. Default (0) means that serial I/O is disabled. */
+/* NB2. THIS OPTION IS DEPRECATED!! */
 unsigned int opt_ser_baud = 0;
+/* opt_com[12]: Config serial port with a string <baud>,DPS,<io-base>,<irq>. */
+unsigned char opt_com1[30] = "", opt_com2[30] = "";
 /* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
 unsigned int opt_dom0_mem = 16000;
 /* opt_ifname: Name of physical network interface to use. */
@@ -77,8 +83,10 @@ static struct {
     enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL } type;
     void *var;
 } opts[] = {
-    { "console",          OPT_UINT, &opt_console },
+    { "console",          OPT_STR,  &opt_console },
     { "ser_baud",         OPT_UINT, &opt_ser_baud },
+    { "com1",             OPT_STR,  &opt_com1 },
+    { "com2",             OPT_STR,  &opt_com2 },
     { "dom0_mem",         OPT_UINT, &opt_dom0_mem }, 
     { "ifname",           OPT_STR,  &opt_ifname },
     { "noht",             OPT_BOOL, &opt_noht },
@@ -92,31 +100,16 @@ static struct {
 };
 
 
-void cmain (unsigned long magic, multiboot_info_t *mbi)
+void cmain(unsigned long magic, multiboot_info_t *mbi)
 {
     struct task_struct *new_dom;
     dom0_createdomain_t dom0_params;
     unsigned long max_page;
-    unsigned char *cmdline;
+    unsigned char *cmdline, *p;
     module_t *mod;
     int i;
 
-    /*
-     * Note that serial output cannot be done properly until after 
-     * command-line arguments have been parsed, and the required baud rate is 
-     * known. Any messages before that will be output using the settings of 
-     * the bootloader, for example.
-     */
-
-    if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
-    {
-        init_vga();
-        cls();
-        printk("Invalid magic number: 0x%x\n", (unsigned)magic);
-        for ( ; ; ) ;
-    }
-
-    /* Parse the command line. */
+    /* Parse the command-line options. */
     cmdline = (unsigned char *)(mbi->cmdline ? __va(mbi->cmdline) : NULL);
     if ( cmdline != NULL )
     {
@@ -158,10 +151,28 @@ void cmain (unsigned long magic, multiboot_info_t *mbi)
         }
     }
 
-    init_serial();
+    /* Backward compatibility with deprecated 'ser_baud=' cmdline option. */
+    if ( opt_ser_baud != 0 )
+        sprintf(opt_com1, "%u,8n1", opt_ser_baud);
+
+    /* We initialise the serial devices very early so we can get debugging. */
+    serial_init_stage1();
+
+    /* Where should console output go? */
+    for ( p = opt_console; p != NULL; p = strchr(p, ',') )
+    {
+        if ( *p == ',' )
+            p++;
+        if ( strncmp(p, "com", 3) == 0 )
+            sercon_handle = parse_serial_handle(p);
+        else if ( strncmp(p, "vga", 3) == 0 )
+            vgacon_enabled = 1;
+    }
+
+    /* Set up VGA console output, if it was enabled. */
     init_vga();
-    cls();
 
+    /* HELLO WORLD --- start-of-day banner text. */
     printk(XEN_BANNER);
     printk(" http://www.cl.cam.ac.uk/netos/xen\n");
     printk(" University of Cambridge Computer Laboratory\n\n");
@@ -170,6 +181,16 @@ void cmain (unsigned long magic, multiboot_info_t *mbi)
            XEN_COMPILE_BY, XEN_COMPILE_DOMAIN,
            XEN_COMPILER, XEN_COMPILE_DATE);
 
+    if ( opt_ser_baud != 0 )
+        printk("**WARNING**: Xen option 'ser_baud=' is deprecated! "
+               "Use 'com1=' instead.\n");
+
+    if ( magic != MULTIBOOT_BOOTLOADER_MAGIC )
+    {
+        printk("FATAL ERROR: Invalid magic number: 0x%08lx\n", magic);
+        for ( ; ; ) ;
+    }
+
     /* We require memory and module information. */
     if ( (mbi->flags & 9) != 9 )
     {
@@ -245,60 +266,20 @@ void cmain (unsigned long magic, multiboot_info_t *mbi)
 }
 
 
-#define SERIAL_BASE 0x3f8
-#define RX_BUF      0
-#define TX_HOLD     0
-#define INT_ENABLE  1
-#define INT_IDENT   2
-#define DATA_FORMAT 3
-#define LINE_CTL    4
-#define LINE_STATUS 5
-#define LINE_IN     6
-#define DIVISOR_LO  0
-#define DIVISOR_HI  1
-
-void init_serial(void)
-{
-    if ( !SERIAL_ENABLED )
-        return;
-
-    /* 'opt_ser_baud' baud, no parity, 1 stop bit, 8 data bits. */
-    outb(0x83, SERIAL_BASE+DATA_FORMAT);
-    outb(115200/opt_ser_baud, SERIAL_BASE+DIVISOR_LO);
-    outb(0, SERIAL_BASE+DIVISOR_HI);
-    outb(0x03, SERIAL_BASE+DATA_FORMAT);
-    
-    /* DTR and RTS should both be high, to keep other end happy. */
-    outb(0x02, SERIAL_BASE+LINE_CTL);
-
-    /* No interrupts. */
-    outb(0x00, SERIAL_BASE+INT_ENABLE);
-}
-
-
-#ifdef CONFIG_OUTPUT_SERIAL
-void putchar_serial(unsigned char c)
-{
-    if ( !SERIAL_ENABLED )
-        return;
-    if ( c == '\n' ) putchar_serial('\r');
-    while ( !(inb(SERIAL_BASE+LINE_STATUS)&(1<<5)) ) barrier();
-    outb(c, SERIAL_BASE+TX_HOLD);
-}
-#else
-void putchar_serial(unsigned char c) {}
-#endif
-
-
-#ifdef CONFIG_OUTPUT_CONSOLE
-
 /* VGA text (mode 3) definitions. */
 #define COLUMNS            80
 #define LINES      25
 #define ATTRIBUTE    7
-#define VIDEO      __va(0xB8000)
 
-int detect_video(void *video_base)
+/* Clear the screen and initialize VIDEO, XPOS and YPOS.  */
+static void cls(void)
+{
+    memset(video, 0, COLUMNS * LINES * 2);
+    xpos = ypos = 0;
+    outw(10+(1<<(5+8)), 0x3d4); /* cursor off */
+}
+
+static int detect_video(void *video_base)
 {
     volatile u16 *p = (volatile u16 *)video_base;
     u16 saved1 = p[0], saved2 = p[1];
@@ -320,7 +301,7 @@ int detect_video(void *video_base)
     return video_found;
 }
 
-int detect_vga(void)
+static int detect_vga(void)
 {
     /*
      * Look at a number of well-known locations. Even if video is not at
@@ -337,7 +318,7 @@ int detect_vga(void)
 }
 
 /* This is actually code from vgaHWRestore in an old version of XFree86 :-) */
-void init_vga(void)
+static void init_vga(void)
 {
     /* The following VGA state was saved from a chip in text mode 3. */
     static unsigned char regs[] = {
@@ -357,13 +338,13 @@ void init_vga(void)
     int i, j = 0;
     volatile unsigned char tmp;
 
-    if ( !opt_console )
+    if ( !vgacon_enabled )
         return;
 
     if ( !detect_vga() )
     {
         printk("No VGA adaptor detected!\n");
-        opt_console = 0;
+        vgacon_enabled = 0;
         return;
     }
 
@@ -391,26 +372,8 @@ void init_vga(void)
     
     tmp = inb(0x3da);
     outb(0x20, 0x3c0);
-}
-
-
-/* Clear the screen and initialize VIDEO, XPOS and YPOS.  */
-void cls(void)
-{
-    int i;
 
-    if ( !opt_console )
-        return;
-
-    video = (unsigned char *) VIDEO;
-    
-    for (i = 0; i < COLUMNS * LINES * 2; i++)
-        *(video + i) = 0;
-    
-    xpos = 0;
-    ypos = 0;
-    
-    outw(10+(1<<(5+8)), 0x3d4); /* cursor off */
+    cls();
 }
 
 
@@ -431,9 +394,9 @@ static void put_newline(void)
 }
 
 
-void putchar_console(int c)
+static void putchar_console(int c)
 {
-    if ( !opt_console )
+    if ( !vgacon_enabled )
         return;
 
     if ( c == '\n' )
@@ -442,54 +405,34 @@ void putchar_console(int c)
     }
     else
     {
-        *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
-        *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
-        
-        xpos++;
-        if (xpos >= COLUMNS)
+        video[(xpos + ypos * COLUMNS) * 2]     = c & 0xFF;
+        video[(xpos + ypos * COLUMNS) * 2 + 1] = ATTRIBUTE;
+        if ( ++xpos >= COLUMNS )
             put_newline();
     }
 }
 
-#else
-
-void init_vga(void) {}
-void cls(void) {}
-void putchar_console(int c) {}
-
-#endif
-
-#ifdef CONFIG_OUTPUT_CONSOLE_RING
 
 void putchar_console_ring(int c)
 {
-    if (console_ring.len < CONSOLE_RING_SIZE)
+    if ( console_ring.len < CONSOLE_RING_SIZE )
         console_ring.buf[console_ring.len++] = (char)c;
 }
 
-#else
-
-void putchar_console_ring(int c) {}
-
-#endif
-
-
-static void putchar(int c)
-{
-    if ( (c != '\n') && ((c < 32) || (c > 126)) ) return;
-    putchar_serial(c);
-    putchar_console(c);
-    putchar_console_ring(c);
-}
-
 
 static inline void __putstr(const char *str)
 {
-    while ( *str ) putchar(*str++);
+    int c;
+    serial_puts(sercon_handle, str);
+    while ( (c = *str++) != '\0' )
+    {
+        putchar_console(c);
+        putchar_console_ring(c);
+    }
 }
 
 
-void printf (const char *fmt, ...)
+void printf(const char *fmt, ...)
 {
     va_list args;
     char buf[128];
@@ -510,7 +453,7 @@ void printf (const char *fmt, ...)
     }
 
     spin_lock_irqsave(&console_lock, flags);
-    while ( *p ) putchar(*p++);
+    __putstr(p);
     spin_unlock_irqrestore(&console_lock, flags);
 }
 
@@ -633,11 +576,12 @@ long do_console_write(char *str, unsigned int count)
 {
 #define SIZEOF_BUF 256
     unsigned char safe_str[SIZEOF_BUF+1];
-    unsigned char exported_str[SIZEOF_BUF+2];
-    unsigned char dom_id[5];
+    unsigned char single_line[SIZEOF_BUF+2];
+    unsigned char line_header[30];
     unsigned char *p;
+    unsigned char  c;
     unsigned long flags;
-    int j;
+    int            j;
     
     if ( count == 0 )
         return 0;
@@ -649,38 +593,32 @@ long do_console_write(char *str, unsigned int count)
         return -EFAULT;
     safe_str[count] = '\0';
     
+    sprintf(line_header, "DOM%llu: ", current->domain);
+    
     p = safe_str;
     while ( *p != '\0' )
     {
         j = 0;
 
-        spin_lock_irqsave(&console_lock, flags);
-        
-        __putstr("DOM"); 
-        sprintf(dom_id, "%llu", current->domain);
-        __putstr(dom_id);
-        __putstr(": ");
-        
-        while ( (*p != '\0') && (*p != '\n') )
+        while ( (c = *p++) != '\0' )
         {
-            exported_str[j++] = *p;
-            putchar(*p);
-            p++;
+            if ( c == '\n' )
+                break;
+            if ( (c < 32) || (c > 126) )
+                continue;
+            single_line[j++] = c;
         }
 
-        if ( *p == '\n' )
-            p++;
+        single_line[j++] = '\n';
+        single_line[j++] = '\0';
 
-        putchar('\n');
-        
+        spin_lock_irqsave(&console_lock, flags);
+        __putstr(line_header);
+        __putstr(single_line);
         spin_unlock_irqrestore(&console_lock, flags);
 
         if ( current->domain != 0 )
-        {
-            exported_str[j++] = '\n';
-            exported_str[j++] = '\0';
-            console_export(exported_str, j);
-        }
+            console_export(single_line, j);
     }
 
     return 0;
index 0a99969113243519d4b38ec47523f02a5753b959..06e25317739b74f2d64a6060470bcebb2f264933 100644 (file)
@@ -2,6 +2,8 @@
 #include <xeno/keyhandler.h> 
 #include <xeno/reboot.h>
 #include <xeno/event.h>
+#include <xeno/console.h>
+#include <xeno/serial.h>
 
 #define KEY_MAX 256
 #define STR_MAX  64
@@ -18,21 +20,21 @@ void add_key_handler(u_char key, key_handler *handler, char *desc)
     int i; 
     char *str; 
 
-    if(key_table[key].handler != NULL
+    if ( key_table[key].handler != NULL 
        printk("Warning: overwriting handler for key 0x%x\n", key); 
 
     key_table[key].handler = handler; 
 
     str = key_table[key].desc; 
-    for(i = 0; i < STR_MAX; i++) {
-       if(*desc) 
+    for ( i = 0; i < STR_MAX; i++ )
+    {
+       if ( *desc != '\0' ) 
            *str++ = *desc++; 
-       else break; 
+       else
+            break; 
     }
-    if (i == STR_MAX
+    if ( i == STR_MAX 
        key_table[key].desc[STR_MAX-1] = '\0'; 
-
-    return; 
 }
 
 key_handler *get_key_handler(u_char key)
@@ -40,42 +42,43 @@ key_handler *get_key_handler(u_char key)
     return key_table[key].handler; 
 }
 
+static void serial_rx(unsigned char c, struct pt_regs *regs)
+{
+    key_handler *handler;
+    if ( (handler = get_key_handler(c)) != NULL )
+        (*handler)(c, NULL, regs);
+}
 
 static void show_handlers(u_char key, void *dev_id, struct pt_regs *regs) 
 {
     int i; 
 
     printk("'%c' pressed -> showing installed handlers\n", key); 
-    for(i=0; i < KEY_MAX; i++
-       if(key_table[i].handler
+    for ( i = 0; i < KEY_MAX; i++ 
+       if ( key_table[i].handler != NULL 
            printk(" key '%c' (ascii '%02x') => %s\n", 
                        (i<33 || i>126)?(' '):(i),i,
                        key_table[i].desc);
-    return; 
 }
 
 
 static void dump_registers(u_char key, void *dev_id, struct pt_regs *regs) 
 {
     extern void show_registers(struct pt_regs *regs); 
-
     printk("'%c' pressed -> dumping registers\n", key); 
     show_registers(regs); 
-    return; 
 }
 
 static void halt_machine(u_char key, void *dev_id, struct pt_regs *regs) 
 {
     printk("'%c' pressed -> rebooting machine\n", key); 
     machine_restart(NULL); 
-    return; 
 }
 
 static void kill_dom0(u_char key, void *dev_id, struct pt_regs *regs) 
 {
     printk("'%c' pressed -> gracefully rebooting machine\n", key); 
     kill_other_domain(0, 0);
-    return;
 }
 
 
@@ -137,12 +140,12 @@ void audit_all_pages(u_char key, void *dev_id, struct pt_regs *regs);
 #endif
 
 
-void initialize_keytable(
+void initialize_keytable(void)
 {
     int i; 
 
     /* first initialize key handler table */
-    for(i = 0; i < KEY_MAX; i++
+    for ( i = 0; i < KEY_MAX; i++ 
        key_table[i].handler = (key_handler *)NULL; 
        
     /* setup own handlers */
@@ -160,4 +163,6 @@ void initialize_keytable()
     add_key_handler('m', reaudit_pages, "re-audit pages");
     add_key_handler('M', audit_all_pages, "audit all pages");
 #endif
+
+    serial_set_rx_handler(sercon_handle, serial_rx);
 }
index e7caf7a60ba545bd17785a0de5fabddc9f18eca9..bc1a5b530bf8ed7f89cdeaf3e76ed55ca34bd4ed 100644 (file)
 #include <asm/domain_page.h>
 
 #ifndef NDEBUG
-#define MEM_LOG(_f, _a...)                           \
+#define MEM_LOG(_f, _a...)                             \
   printk("DOM%llu: (file=memory.c, line=%d) " _f "\n", \
-         current->domain, __LINE__, ## _a )
+         current->domain , __LINE__ , ## _a )
 #else
 #define MEM_LOG(_f, _a...) ((void)0)
 #endif
diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c
new file mode 100644 (file)
index 0000000..b936da4
--- /dev/null
@@ -0,0 +1,398 @@
+/******************************************************************************
+ * serial.c
+ * 
+ * Driver for 16550-series UARTs. This driver is to be kept within Xen as
+ * it permits debugging of seriously-toasted machines (e.g., in situations
+ * where a device driver within a guest OS would be inaccessible).
+ * 
+ * Copyright (c) 2003-2004, K A Fraser
+ */
+
+#include <asm-i386/io.h>
+#include <xeno/sched.h>
+#include <xeno/keyhandler.h> 
+#include <xeno/reboot.h>
+#include <xeno/irq.h>
+#include <xeno/serial.h>
+#include <asm/pdb.h>
+
+/* Register offsets */
+#define RBR             0x00    /* receive buffer       */
+#define THR             0x00    /* transmit holding     */
+#define IER             0x01    /* interrupt enable     */
+#define IIR             0x02    /* interrupt identity   */
+#define FCR             0x02    /* FIFO control         */
+#define LCR             0x03    /* line control         */
+#define MCR             0x04    /* Modem control        */
+#define LSR             0x05    /* line status          */
+#define MSR             0x06    /* Modem status         */
+#define DLL             0x00    /* divisor latch (ls) ( DLAB=1)        */
+#define DLM             0x01    /* divisor latch (ms) ( DLAB=1)        */
+
+/* Interrupt Enable Register */
+#define IER_ERDAI       0x01    /* rx data recv'd       */
+#define IER_ETHREI      0x02    /* tx reg. empty        */
+#define IER_ELSI        0x04    /* rx line status       */
+#define IER_EMSI        0x08    /* MODEM status                */
+
+/* FIFO control register */
+#define FCR_ENABLE      0x01    /* enable FIFO          */
+#define FCR_CLRX        0x02    /* clear Rx FIFO        */
+#define FCR_CLTX        0x04    /* clear Tx FIFO        */
+#define FCR_DMA         0x10    /* enter DMA mode       */
+#define FCR_TRG1        0x00    /* Rx FIFO trig lev 1   */
+#define FCR_TRG4        0x40    /* Rx FIFO trig lev 4   */
+#define FCR_TRG8        0x80    /* Rx FIFO trig lev 8   */
+#define FCR_TRG14       0xc0    /* Rx FIFO trig lev 14  */
+
+/* Line control register */
+#define LCR_DLAB        0x80    /* Divisor Latch Access */
+
+/* Modem Control Register */
+#define MCR_DTR         0x01    /* Data Terminal Ready  */
+#define MCR_RTS         0x02    /* Request to Send      */
+#define MCR_OUT2        0x08    /* OUT2: interrupt mask */
+
+/* Line Status Register */
+#define LSR_DR          0x01    /* Data ready           */
+#define LSR_OE          0x02    /* Overrun              */
+#define LSR_PE          0x04    /* Parity error         */
+#define LSR_FE          0x08    /* Framing error        */
+#define LSR_BI          0x10    /* Break                */
+#define LSR_THRE        0x20    /* Xmit hold reg empty  */
+#define LSR_TEMT        0x40    /* Xmitter empty        */
+#define LSR_ERR         0x80    /* Error                */
+
+/* These parity settings can be ORed directly into the LCR. */
+#define PARITY_NONE     (0<<3)
+#define PARITY_ODD      (1<<3)
+#define PARITY_EVEN     (3<<3)
+#define PARITY_MARK     (5<<3)
+#define PARITY_SPACE    (7<<3)
+
+typedef struct {
+    int          baud, data_bits, parity, stop_bits, io_base, irq;
+    serial_rx_fn rx_lo, rx_hi, rx;
+    spinlock_t   lock;
+} uart_t;
+
+static uart_t com[2] = {
+    { 0, 0, 0, 0, 0x3f8, 4,
+      NULL, NULL, NULL,
+      SPIN_LOCK_UNLOCKED },
+    { 0, 0, 0, 0, 0x2f8, 3,
+      NULL, NULL, NULL,
+      SPIN_LOCK_UNLOCKED }
+};
+
+#define UART_ENABLED(_u) ((_u)->baud != 0)
+#define DISABLE_UART(_u) ((_u)->baud = 0)
+
+
+/***********************
+ * PRIVATE FUNCTIONS
+ */
+
+static void uart_rx(uart_t *uart, struct pt_regs *regs)
+{
+    unsigned char c;
+
+    if ( !UART_ENABLED(uart) )
+        return;
+
+    /*
+     * No need for the uart spinlock here. Only the uart's own interrupt
+     * handler will read from the RBR and the handler isn't reentrant.
+     */
+    while ( inb(uart->io_base + LSR) & LSR_DR )
+    {
+        c = inb(uart->io_base + RBR);
+        if ( uart->rx != NULL )
+            uart->rx(c, regs);
+        else if ( (c & 0x80) && (uart->rx_hi != NULL) )
+            uart->rx_hi(c&0x7f, regs);
+        else if ( !(c & 0x80) && (uart->rx_lo != NULL) )
+            uart->rx_lo(c&0x7f, regs);
+    }
+}
+
+static void serial_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    uart_rx((uart_t *)dev_id, regs);
+}
+
+static inline void __serial_putc(uart_t *uart, int handle, unsigned char c)
+{
+    if ( (c == '\n') && (handle & SERHND_COOKED) )
+        __serial_putc(uart, handle, '\r');
+
+    if ( handle & SERHND_HI )
+        c |= 0x80;
+    else if ( handle & SERHND_LO )
+        c &= ~0x7f;
+
+    while ( !(inb(uart->io_base + LSR) & LSR_THRE) )
+        barrier();
+
+    outb(c, uart->io_base + THR);
+}
+
+#define PARSE_ERR(_f, _a...)                 \
+    do {                                     \
+        printk( "ERROR: " _f "\n" , ## _a ); \
+        DISABLE_UART(uart);                  \
+        return;                              \
+} while ( 0 )
+        
+static void parse_port_config(char *conf, uart_t *uart)
+{
+    if ( *conf == '\0' )
+        return;
+
+    uart->baud = simple_strtol(conf, &conf, 10);
+    if ( (uart->baud < 1200) || (uart->baud > 115200) )
+        PARSE_ERR("Baud rate %d outside supported range.", uart->baud);
+
+    if ( *conf != ',' )
+        PARSE_ERR("Missing data/parity/stop specifiers.");
+
+    conf++;
+
+    uart->data_bits = simple_strtol(conf, &conf, 10);
+    if ( (uart->data_bits < 5) || (uart->data_bits > 8) )
+        PARSE_ERR("%d data bits are unsupported.", uart->data_bits);
+
+    switch ( *conf )
+    {
+    case 'n':
+        uart->parity = PARITY_NONE;
+        break;
+    case 'o': 
+        uart->parity =  PARITY_ODD;
+        break;
+    case 'e': 
+        uart->parity =  PARITY_EVEN;
+        break;
+    case 'm': 
+        uart->parity =  PARITY_MARK;
+        break;
+    case 's': 
+        uart->parity =  PARITY_SPACE;
+        break;
+
+    default:
+        PARSE_ERR("Invalid parity specifier '%c'.", *conf);
+    }
+
+    conf++;
+
+    uart->stop_bits = simple_strtol(conf, &conf, 10);
+    if ( (uart->stop_bits < 1) || (uart->stop_bits > 2) )
+        PARSE_ERR("%d stop bits are unsupported.", uart->stop_bits);
+
+    if ( *conf == ',' )
+    {
+        conf++;
+
+        uart->io_base = simple_strtol(conf, &conf, 0);
+        if ( (uart->io_base <= 0x0000) || (uart->io_base > 0xfff0) )
+            PARSE_ERR("I/O port base 0x%x is outside the supported range.",
+                      uart->io_base);
+
+        if ( *conf != ',' )
+            PARSE_ERR("Missing IRQ specifier.");
+            
+        conf++;
+            
+        uart->irq = simple_strtol(conf, &conf, 10);
+        if ( (uart->irq <= 0) || (uart->irq >= 32) )
+            PARSE_ERR("IRQ %d is outside the supported range.", uart->irq);
+    }
+}
+
+static void uart_config_stage1(uart_t *uart)
+{
+    unsigned char lcr;
+
+    if ( !UART_ENABLED(uart) )
+        return;
+
+    lcr = (uart->data_bits - 5) | ((uart->stop_bits - 1) << 2) | uart->parity;
+
+    /* No interrupts. */
+    outb(0, uart->io_base + IER);
+
+    /* Line control and baud-rate generator. */
+    outb(lcr | LCR_DLAB,    uart->io_base + LCR);
+    outb(115200/uart->baud, uart->io_base + DLL); /* baud lo */
+    outb(0,                 uart->io_base + DLM); /* baud hi */
+    outb(lcr,               uart->io_base + LCR); /* parity, data, stop */
+
+    /* No flow ctrl: DTR and RTS are both wedged high to keep remote happy. */
+    outb(MCR_DTR | MCR_RTS, uart->io_base + MCR);
+
+    /* Enable and clear the FIFOs. Set a large trigger threshold. */
+    outb(FCR_ENABLE | FCR_CLRX | FCR_CLTX | FCR_TRG14, uart->io_base + FCR);
+}
+
+static void uart_config_stage2(uart_t *uart)
+{
+    int rc;
+
+    if ( !UART_ENABLED(uart) )
+        return;
+
+    rc = request_irq(uart->irq, 
+                     serial_interrupt, 
+                     SA_NOPROFILE, 
+                     "serial", 
+                     uart);
+    if ( rc != 0 )
+        printk("ERROR: Failed to allocate serial IRQ %d\n", uart->irq);
+
+    /* For sanity, clear the receive FIFO. */
+    outb(FCR_ENABLE | FCR_CLRX | FCR_TRG14, uart->io_base + FCR);
+
+    /* Master interrupt enable; also keep DTR/RTS asserted. */
+    outb(MCR_OUT2 | MCR_DTR | MCR_RTS, uart->io_base + MCR);
+
+    /* Enable receive interrupts. */
+    outb(IER_ERDAI, uart->io_base + IER);
+}
+
+
+/***********************
+ * PUBLIC FUNCTIONS
+ */
+
+void serial_init_stage1(void)
+{
+    extern unsigned char opt_com1[], opt_com2[];
+
+    parse_port_config(opt_com1, &com[0]);
+    parse_port_config(opt_com2, &com[1]);
+
+    uart_config_stage1(&com[0]);
+    uart_config_stage1(&com[1]);
+}
+
+void serial_init_stage2(void)
+{
+    uart_config_stage2(&com[0]);
+    uart_config_stage2(&com[1]);
+}
+
+int parse_serial_handle(char *conf)
+{
+    int handle;
+
+    /* Silently fail if user has explicitly requested no serial I/O. */
+    if ( strcmp(conf, "none") == 0 )
+        return -1;
+
+    if ( strncmp(conf, "com", 3) != 0 )
+        goto fail;
+
+    switch ( conf[3] )
+    {
+    case '1':
+        handle = 0;
+        break;
+    case '2':
+        handle = 1;
+        break;
+    default:
+        goto fail;
+    }
+
+    if ( !UART_ENABLED(&com[handle]) )
+    {
+        printk("ERROR: cannot use unconfigured serial port COM%d\n", handle+1);
+        return -1;
+    }
+
+    if ( conf[4] == 'H' )
+        handle |= SERHND_HI;
+    else if ( conf[4] == 'L' )
+        handle |= SERHND_LO;
+
+    handle |= SERHND_COOKED;
+
+    return handle;
+
+ fail:
+    printk("ERROR: bad serial-interface specification '%s'\n", conf);
+    return -1;
+}
+
+void serial_set_rx_handler(int handle, serial_rx_fn fn)
+{
+    uart_t *uart = &com[handle & SERHND_IDX];
+    unsigned long flags;
+
+    if ( handle == -1 )
+        return;
+
+    spin_lock_irqsave(&uart->lock, flags);
+
+    if ( uart->rx != NULL )
+        goto fail;
+
+    if ( handle & SERHND_LO )
+    {
+        if ( uart->rx_lo != NULL )
+            goto fail;
+        uart->rx_lo = fn;        
+    }
+    else if ( handle & SERHND_HI )
+    {
+        if ( uart->rx_hi != NULL )
+            goto fail;
+        uart->rx_hi = fn;
+    }
+    else
+    {
+        if ( (uart->rx_hi != NULL) || (uart->rx_lo != NULL) )
+            goto fail;
+        uart->rx = fn;
+    }
+
+    spin_unlock_irqrestore(&uart->lock, flags);
+    return;
+
+ fail:
+    spin_unlock_irqrestore(&uart->lock, flags);
+    printk("ERROR: Conflicting receive handlers for COM%d\n", 
+           handle & SERHND_IDX);
+}
+
+void serial_putc(int handle, unsigned char c)
+{
+    uart_t *uart = &com[handle & SERHND_IDX];
+    unsigned long flags;
+
+    if ( handle == -1 )
+        return;
+
+    spin_lock_irqsave(&uart->lock, flags);
+
+    __serial_putc(uart, handle, c);
+
+    spin_unlock_irqrestore(&uart->lock, flags);
+}
+
+void serial_puts(int handle, const unsigned char *s)
+{
+    uart_t *uart = &com[handle & SERHND_IDX];
+    unsigned long flags;
+
+    if ( handle == -1 )
+        return;
+
+    spin_lock_irqsave(&uart->lock, flags);
+
+    while ( *s != '\0' )
+        __serial_putc(uart, handle, *s++);
+
+    spin_unlock_irqrestore(&uart->lock, flags);
+}
diff --git a/xen/drivers/char/xen_serial.c b/xen/drivers/char/xen_serial.c
deleted file mode 100644 (file)
index 41e411d..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-#include <asm-i386/io.h>
-#include <xeno/sched.h>    /* this has request_irq() proto for some reason */
-#include <xeno/keyhandler.h> 
-#include <xeno/reboot.h>
-#include <xeno/irq.h>
-#include <asm/pdb.h>
-
-/* Register offsets */
-#define NS16550_RBR    0x00    /* receive buffer       */
-#define NS16550_THR    0x00    /* transmit holding     */
-#define NS16550_IER    0x01    /* interrupt enable     */
-#define NS16550_IIR    0x02    /* interrupt identity   */
-#define NS16550_FCR     0x02    /* FIFO control         */
-#define NS16550_LCR    0x03    /* line control         */
-#define NS16550_MCR    0x04    /* MODEM control        */
-#define NS16550_LSR    0x05    /* line status          */
-#define NS16550_MSR    0x06    /* MODEM status         */
-#define NS16550_SCR    0x07    /* scratch              */
-#define NS16550_DDL    0x00    /* divisor latch (ls) ( DLAB=1) */
-#define NS16550_DLM    0x01    /* divisor latch (ms) ( DLAB=1) */
-
-/* Interrupt enable register */
-#define NS16550_IER_ERDAI      0x01    /* rx data recv'd       */
-#define NS16550_IER_ETHREI     0x02    /* tx reg. empty        */
-#define NS16550_IER_ELSI       0x04    /* rx line status       */
-#define NS16550_IER_EMSI       0x08    /* MODEM status         */
-
-/* FIFO control register */
-#define NS16550_FCR_ENABLE      0x01    /* enable FIFO          */
-#define NS16550_FCR_CLRX        0x02    /* clear Rx FIFO        */
-#define NS16550_FCR_CLTX        0x04    /* clear Tx FIFO        */
-#define NS16550_FCR_DMA         0x10    /* enter DMA mode       */
-#define NS16550_FCR_TRG1        0x00    /* Rx FIFO trig lev 1   */
-#define NS16550_FCR_TRG4        0x40    /* Rx FIFO trig lev 4   */
-#define NS16550_FCR_TRG8        0x80    /* Rx FIFO trig lev 8   */
-#define NS16550_FCR_TRG14       0xc0    /* Rx FIFO trig lev 14  */
-
-/* MODEM control register */
-#define NS16550_MCR_DTR        0x01    /* Data Terminal Ready  */
-#define NS16550_MCR_RTS        0x02    /* Request to Send      */
-#define NS16550_MCR_OUT1        0x04    /* OUT1: unused         */
-#define NS16550_MCR_OUT2        0x08    /* OUT2: interrupt mask */
-#define NS16550_MCR_LOOP       0x10    /* Loop                 */
-
-#define LSR_DR   0x01  /* Data ready */
-#define LSR_OE   0x02  /* Overrun */
-#define LSR_PE   0x04  /* Parity error */
-#define LSR_FE   0x08  /* Framing error */
-#define LSR_BI   0x10  /* Break */
-#define LSR_THRE 0x20  /* Xmit holding register empty */
-#define LSR_TEMT 0x40  /* Xmitter empty */
-#define LSR_ERR  0x80  /* Error */
-
-#define SERIAL_COM1 0x3f8
-#define SERIAL_COM2 0x2f8
-
-void initialize_serial_port(int base);
-
-int serial_com_base = SERIAL_COM1;
-int debug_com_base  = SERIAL_COM1;
-
-static int serial_echo = 0;       /* default is not to echo; change with '~' */
-
-void toggle_echo(u_char key, void *dev_id, struct pt_regs *regs) 
-{
-    serial_echo = !serial_echo; 
-}
-
-void debug_set_com_port(int port)
-{
-    debug_com_base = port == 1 ? SERIAL_COM1 : SERIAL_COM2;
-    if (port == 2) initialize_serial_port(SERIAL_COM2);
-}
-
-int debug_testchar()                                /* character available? */
-{
-    return (inb(debug_com_base + NS16550_LSR) & LSR_DR);
-}
-
-u_char debug_getchar()
-{
-    while (! (inb(debug_com_base + NS16550_LSR) & LSR_DR));/* wait for char */
-    return inb(debug_com_base + NS16550_RBR);
-}
-
-void debug_putch(u_char c)
-{
-    while (! (inb(debug_com_base + NS16550_LSR) & LSR_THRE));
-                                                            /* wait for idle */
-    outb(c, debug_com_base + NS16550_RBR);
-}
-
-void debug_putchar(u_char c)
-{
-    debug_putch(c);
-    if (c == '\n') debug_putch('\r');
-}
-
-
-
-int serial_testchar()                                /* character available? */
-{
-    return (inb(serial_com_base + NS16550_LSR) & LSR_DR);
-}
-
-u_char serial_getchar()
-{
-    while (! (inb(serial_com_base + NS16550_LSR) & LSR_DR));/* wait for char */
-    return inb(serial_com_base + NS16550_RBR);
-}
-
-void serial_putch(u_char c)
-{
-    while (! (inb(serial_com_base + NS16550_LSR) & LSR_THRE));
-                                                            /* wait for idle */
-    outb(c, serial_com_base + NS16550_RBR);
-}
-
-void serial_putchar(u_char c)
-{
-    serial_putch(c);
-    if ( c == '\n' )
-        serial_putch('\r');
-}
-
-static spinlock_t serial_lock;
-
-static void serial_rx_int(int irq, void *dev_id, struct pt_regs *regs)
-{
-    u_char c; 
-    key_handler *handler; 
-    unsigned long flags;
-
-    spin_lock_irqsave(&serial_lock, flags);
-
-    while ( serial_testchar() )
-    {
-        c = serial_getchar();
-
-       if ( c & 0x80 )
-       {
-           pdb_serial_input(c & 0x7f, regs);
-       }
-       else
-       {
-           if ( (handler = get_key_handler(c)) != NULL ) 
-               (*handler)(c, dev_id, regs); 
-
-           if ( serial_echo ) 
-               serial_putch(c);
-       }
-    }
-
-    spin_unlock_irqrestore(&serial_lock, flags);
-}
-
-void initialize_serial() 
-{
-    if ( !SERIAL_ENABLED )
-        return;
-
-    spin_lock_init(&serial_lock);
-    
-    /* setup key handler */
-    add_key_handler('~', toggle_echo, "toggle serial echo");
-
-    initialize_serial_port(SERIAL_COM1);
-}
-
-/* warning: no protection against duplicate initialization */
-void initialize_serial_port(int base)
-{    
-    int rc; 
-
-    /* This assumes we have a 16550. It's pretty darned likely really! */
-    /* Clear FIFOs, enable, trigger at 1 byte */
-    outb(NS16550_FCR_TRG1 | NS16550_FCR_ENABLE |
-         NS16550_FCR_CLRX  | NS16550_FCR_CLTX, 
-         base + NS16550_FCR);
-
-    /* Enable receive interrupts. Also remember to keep DTR/RTS asserted. */
-    outb(NS16550_MCR_OUT2|NS16550_MCR_DTR|NS16550_MCR_RTS, 
-         base + NS16550_MCR);
-    outb(NS16550_IER_ERDAI, 
-         base + NS16550_IER );
-
-    switch(base)
-    {
-    case SERIAL_COM1 :
-    {
-        if( (rc = request_irq(4, serial_rx_int, SA_NOPROFILE, "serial 1", 0)) )
-         printk("initialize_serial: failed to get IRQ4, rc=%d\n", rc); 
-       break;
-    }
-    case SERIAL_COM2 :
-    {
-        if( (rc = request_irq(3, serial_rx_int, SA_NOPROFILE, "serial 2", 0)) )
-         printk("initialize_serial: failed to get IRQ3, rc=%d\n", rc); 
-       break;
-    }
-    default :
-    {
-         printk("initialize_serial: unknown serial base: 0x%d\n", base); 
-    }
-    }
-}
index 6dc740405ddcd08e3d8b7c39e0bb7a098aac4bc1..35cdd22ee4b9b6d3c7335afb2b1fc5572b4ab00c 100644 (file)
 
 #ifndef NDEBUG
 #define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
-                           __FILE__, __LINE__, ## _a)
+                           __FILE__ , __LINE__ , ## _a )
 #define STACK_GUARD
 #else
 #define DPRINTK(_f, _a...) ((void)0)
index 375c4b22150af94d944de3f1579dd09be4141ef8..d68aa893bbf1c14506e6dbfcbe9dd3e778cb16e9 100644 (file)
  * who gets the PS/2 keyboard/mouse events
  */
 
+extern int sercon_handle;
+extern int vgacon_enabled;
+
 #define CONSOLE_ISOWNER(p) (p->domain == 0) 
 #define CONSOLE_OWNER      (find_domain_by_id(0))
 
-
-/*
- * Xen output redirection (in common/kernel.c)
- *
- * This is coarsely done right now - 
- *  - a boot-time option for console output
- *  - a compile-time option for serial output and console output
- *
- * Really, when starting up a guest os with console privilege, we should:
- *  - reset the video to a known state
- *  - stop sending characters (clear 'opt_console')
- *  - allow the guest os access to the video RAM area and keyboard
- * Similarly, when stopping that guest os, we should:
- *  - stop allowing the guest os access to video RAM
- *  - reset the video to a known state
- *  - start sending it console output again (if we so desire)
- *
- * Resetting the video to a known state has not been explored yet, although
- * Xen resets to a VGA text mode at start of day. Also, the notion of
- * privileges for guest os's (e.g. console privilege) has not been explored
- * yet, so this will do for now.
- */
-
-#define CONFIG_OUTPUT_SERIAL  1
-#define CONFIG_OUTPUT_CONSOLE 1
-#define CONFIG_OUTPUT_CONSOLE_RING 1
-
-extern int opt_console;
-
 #define CONSOLE_RING_SIZE      16392
 #define CONSOLE_RING_CLEAR     1
 
index 8cad54f9d1f0ff8684d38c87c21f2b7667de99ce..c3fe557974fc00fbc6bf9fa5dbc95de9dfa22268 100644 (file)
@@ -36,7 +36,6 @@ unsigned char *quad_to_str(unsigned long q, unsigned char *s);
 /* kernel.c */
 #define printk printf
 void printf (const char *format, ...);
-void cls(void);
 void panic(const char *format, ...);
 
 /* vsprintf.c */
diff --git a/xen/include/xeno/serial.h b/xen/include/xeno/serial.h
new file mode 100644 (file)
index 0000000..c24f0c6
--- /dev/null
@@ -0,0 +1,39 @@
+/******************************************************************************
+ * serial.h
+ * 
+ * Driver for 16550-series UARTs. This driver is to be kept within Xen as
+ * it permits debugging of seriously-toasted machines (e.g., in situations
+ * where a device driver within a guest OS would be inaccessible).
+ * 
+ * Copyright (c) 2003-2004, K A Fraser
+ */
+
+#ifndef __XEN_SERIAL_H__
+#define __XEN_SERIAL_H__
+
+#include <asm/ptrace.h>
+
+/* 'Serial handles' are comprise the following fields. */
+#define SERHND_IDX      (1<<0) /* COM1 or COM2?                           */
+#define SERHND_HI       (1<<1) /* Mux/demux each transferred char by MSB. */
+#define SERHND_LO       (1<<2) /* Ditto, except that the MSB is cleared.  */
+#define SERHND_COOKED   (1<<3) /* Newline/carriage-return translation?    */
+
+/* Two-stage initialisation (before/after IRQ-subsystem initialisation). */
+void serial_init_stage1(void);
+void serial_init_stage2(void);
+
+/* Takes a config string and creates a numeric handle on the COM port. */
+int parse_serial_handle(char *conf);
+
+/* Register a character-receive hook on the specified COM port. */
+typedef void (*serial_rx_fn)(unsigned char, struct pt_regs *);
+void serial_set_rx_handler(int handle, serial_rx_fn fn);
+
+/* Transmit a single character via the specified COM port. */
+void serial_putc(int handle, unsigned char c);
+
+/* Transmit a NULL-terminated string via the specified COM port. */
+void serial_puts(int handle, const unsigned char *s);
+
+#endif /* __XEN_SERIAL_H__ */